'''
Store and retrieve user and other information.

WARNING: GMZ does not store the password for the gmail account used to send 
backup files in a secure way. Do not use your main gmail account for the 
purposes of sending the archives.
'''

import os
import pickle 
import bz2

import config

##################################################
#### Config Obj
##################################################

def get_config_path():
    return os.environ["APPDATA"] + "\\GMZ\\config.cfg"

__config = None

def is_configured():
    '''Basic and simple check to see if there is a config file'''
    return os.path.isfile(get_config_path())

def _load_config():
    '''Returns the config dictionary.'''
    configPath = get_config_path()
    if not os.path.isfile(configPath):
        return {}

    try:
        configFile = open(configPath, 'rb')    
        configObjComp = pickle.load(configFile)
    finally:
        configFile.close()
    
    configObj = {}    
    for key, value in configObjComp.iteritems():
        configObj[bz2.decompress(key)] = bz2.decompress(value)
    
    return configObj

def _get_config():
    if config.__config is None:
        config.__config = _load_config()
    
    return __config

def _save_config_changes():
    #'compress' fields to make reading the file more difficult
    #This prevents somebody from just opening the config file and reading
    #the password (it is NOT secure password storage)
    newConfig = {}
    for key, value in config.__config.iteritems():
        newConfig[bz2.compress(key)] = bz2.compress(value)

    #Make sure the save directory exists
    cdir = os.path.dirname(get_config_path())
    if not os.path.exists(cdir):
        os.mkdir(cdir)
    else:
        assert os.path.isdir(cdir)
    
    #Delete the old config file
    if os.path.exists(get_config_path()):
        assert os.path.isfile(get_config_path())
        os.remove(get_config_path())
    
    try:
        configFile = open(get_config_path(), 'wb')    
        pickle.dump(newConfig, configFile)
    finally:
        configFile.close()
    
    #releoad - not necessarily needed
    config.__config = _load_config()

##################################################
#### Config field access
##################################################

def _get_field(field, default=""):
    '''Generic access to a given field (string)
    
    default: defalut value of the field, set to None if the field has no 
    default value and must be explicitly set (will raise KeyError)'''
    try:
        return _get_config()[field]
    except KeyError:
        if default is None:
            raise #TODO: Custom error
        
        #Set the default value and return it
        _set_field(field, default)
        return default

def _set_field(field, value):
    config = _get_config()
    config[field] = str(value)
    _save_config_changes()

##################################################
#### Email
##################################################

def get_guser():
    '''Username of the gmail account which will be used to send the backups'''
    return _get_field("guser")

def set_guser(guser):
    
    _set_field("guser", guser)
    
def get_gpwd():
    '''Password of the gmail account which will be used to send the backups'''
    return _get_field("gpwd")

def set_gpwd(gpwd):
    '''WARNING: The password is not stored in a secure manner'''
    _set_field("gpwd", gpwd)

def get_backupemail():
    '''Email address that the backups will be sent to'''
    return _get_field("backupemail")

def set_backupemail(backupemail):
    _set_field("backupemail", backupemail)


##################################################
#### Archiving Settings
##################################################

def get_desired_arcsize():
    '''Returns desired archive (.zip) size in bytes. Must be less than the 
    maximum file size (defined in arcmgmt)'''
    return 10*(10**6) # 10 mb